home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / xfont.pro < prev    next >
Text File  |  1997-07-08  |  14KB  |  440 lines

  1. ; $Id: xfont.pro,v 1.11 1997/01/15 03:11:50 ali Exp $
  2. ;
  3. ; Copyright (c) 1991-1997, Research Systems, Inc.  All rights reserved.
  4. ;    Unauthorized reproduction prohibited.
  5. ;+
  6. ; NAME:
  7. ;    XFONT
  8. ;
  9. ; PURPOSE:
  10. ;    XFONT is a modal widget for selecting and viewing an X Windows font.
  11. ; CATEGORY:
  12. ;    Widgets, Fonts
  13. ;
  14. ; CALLING SEQUENCE:
  15. ;    Selected_font = XFONT()
  16. ;
  17. ; INPUTS:
  18. ;    No explicit inputs.
  19. ;
  20. ; KEYWORD PARAMETERS:
  21. ;    GROUP:    The widget ID of the widget that calls XFONT. When this
  22. ;          ID is specified, a death of the caller results in a death
  23. ;          of XFONT.
  24. ;    PRESERVE: If set, XFONT saves the server font directory in common
  25. ;          blocks so that subsequent calls to XFONT start-up much
  26. ;          faster. If not set, the common block is cleaned.
  27. ;
  28. ; OUTPUTS:
  29. ;    A string containing the font name.  If nothing is selected, or
  30. ;    the CANCEL button is pressed, a null string is returned.
  31. ;
  32. ; COMMON BLOCKS:
  33. ;    XFONT_COM.
  34. ;
  35. ; SIDE EFFECTS:
  36. ;    Initiates the XManager if it is not already running.
  37. ;    Resets the current X Window font.  
  38. ;
  39. ; RESTRICTIONS:
  40. ;    The current X window font is manipulated without being restored.
  41. ;    This routine does not work on non-X Windows platforms (i.e., Windows
  42. ;    and Macintosh).
  43. ;
  44. ; PROCEDURE:
  45. ;    Create and register the widget and then exit.
  46. ;
  47. ; MODIFICATION HISTORY:
  48. ;    Modified from a template written by: Hans-Joachim Bothe, CreaSo GmbH,
  49. ;        November, 1991, by DMS, RSI, November, 1992.
  50. ;    1 July 1995, AB, Fixed sizing of toggle buttons.
  51. ;    6 July 1995, MWR, Added platform check to return to caller if 
  52. ;        running on Windows or Macintosh.
  53. ;-
  54.  
  55.  
  56.  
  57.  
  58. FUNCTION xfont_select, sstring        ;Find fonts matching sstring
  59. ;  Return -1 if none there....
  60. common xfont_com, s, f, xreg, private, nfields, nreg, uniqi, uniqs, $
  61.     t_buttons, t_list, s_list, s_string, t_button_select, t_text, $
  62.     l_text, to_do, t_selections, selected_font, view_text, $
  63.     view_window, reg_base, priv, display_string, s_text, preserve, $
  64.     point_base, point_txt, size_index
  65.  
  66.  
  67.  
  68. l = replicate(1b, nreg)            ;Matching fonts so far
  69.  
  70. for i=0, n_elements(to_do)-1 do begin
  71.     if s_string[i] ne '*' then begin  ;Search this field
  72.         bad = where(f[i,*] ne s_string[i], count)
  73.         if count gt 0 then l[bad] = 0
  74.         endif
  75.     endfor
  76. return, where(l)
  77. end
  78.  
  79.  
  80. FUNCTION xfont_scal_fname, name
  81. ; Given a font name, s.  See if field 8 (the size field, counting the
  82. ; first '-') contains the string '0'.  If so, substitute the contents of 
  83. ; the point_size text widget, followed by -75-75.
  84. ;    
  85. common xfont_com, s, f, xreg, private, nfields, nreg, uniqi, uniqs, $
  86.     t_buttons, t_list, s_list, s_string, t_button_select, t_text, $
  87.     l_text, to_do, t_selections, selected_font, view_text, $
  88.     view_window, reg_base, priv, display_string, s_text, preserve, $
  89.     point_base, point_txt, size_index
  90.  
  91. t = str_sep(name, '-')
  92. if n_elements(t) lt 11 then return, name
  93. if fix(t[8]) ne 0 then return, name
  94. widget_control, point_txt, GET_VALUE = x
  95. if fix(x[0]) eq 0 then return, name    ;No size specified
  96. t[8] = x        ;Substitute point size
  97. t[9] = '75'        ;Diddle our fields
  98. t[10] = '75'
  99. n = n_elements(t)
  100. r = ''
  101. for i=1, n_elements(t)-1 do r = r + '-' + t[i]   ;Re-combine
  102.  
  103. return ,r
  104. end
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111. PRO xfont_event, event            ;Main & only event procedure
  112.                      
  113. common xfont_com, s, f, xreg, private, nfields, nreg, uniqi, uniqs, $
  114.     t_buttons, t_list, s_list, s_string, t_button_select, t_text, $
  115.     l_text, to_do, t_selections, selected_font, view_text, $
  116.     view_window, reg_base, priv, display_string, s_text, preserve, $
  117.     point_base, point_txt, size_index
  118.  
  119.  
  120.  
  121. WIDGET_CONTROL, event.top, /HOURGLASS
  122. WIDGET_CONTROL, event.id, GET_UVALUE=eventval
  123.  
  124.    ; Determine event type
  125.  
  126. CASE eventval OF
  127.  
  128.     "TBUTTON": BEGIN        ;Font-type button
  129.     if t_button_select ne -1 then $
  130.         widget_control, t_buttons[t_button_select], $
  131.             SET_BUTTON = 0  ;Remove prev
  132.     t_button_select = (where(event.id eq t_buttons))[0]  ;New button
  133.     n = t_button_select
  134.     s_string[n] = '*'    ;Make this one wild
  135.     WIDGET_CONTROL, t_text[n], SET_VALUE = '*'
  136.     q = xfont_select(s_string)    ;Fonts OK so far.
  137.  
  138.     if q[0] ne -1 then begin    ;Anything there?
  139.         t_strings = f[n,q]    ;Names that we can select
  140.         t_selections = uniq(t_strings, sort(t_strings))
  141.         t_selections = t_strings[t_selections]
  142.     endif else t_selections = '<Nothing Matches>'
  143.     WIDGET_CONTROL, t_list, set_value = t_selections
  144.     goto, update_s_list
  145.     ENDCASE
  146.     
  147.     "T_LIST": BEGIN        ;Picked a list item
  148.     if t_button_select eq -1 then return
  149.     s_string[t_button_select] = t_selections[event.index]
  150.     WIDGET_CONTROL, t_text[t_button_select], $
  151.         SET_VALUE = t_selections[event.index]
  152.     q = xfont_select(s_string)    ;Matching fonts
  153.     if t_button_select eq size_index then begin
  154.         i =  s_string[size_index] eq '0' 
  155.         WIDGET_CONTROL, point_base, MAP=i
  156.         endif
  157.     update_s_list:
  158.     selected_font = -1
  159.     if q[0] ne -1 then BEGIN
  160.         WIDGET_CONTROL, s_list, SET_VALUE=s[xreg[q]]
  161.         selected_font = xreg[q[0]]
  162.     ENDIF ELSE WIDGET_CONTROL, s_list, SET_VALUE = '<No matching fonts>'
  163.     WIDGET_CONTROL, l_text, SET_VALUE= strtrim(n_elements(q),2) + $
  164.        ' matching fonts.'
  165.     goto, view_font
  166.     ENDCASE    
  167.  
  168.     "S_LIST": BEGIN
  169.     if priv then selected_font = private[event.index] $
  170.     else begin
  171.         q = xfont_select(s_string)    ;Matching fonts
  172.         selected_font = xreg[q[event.index]]
  173.     endelse
  174. ;     print,s(selected_font)
  175.   view_font:
  176.     if selected_font lt 0 then begin
  177.         WIDGET_CONTROL, view_text, SET_VALUE = 'No font selected'
  178.         return
  179.         endif
  180.     font = xfont_scal_fname(s[selected_font])
  181.     WIDGET_CONTROL, view_text, SET_VALUE=font
  182.     swin = !d.window
  183.     wset, view_window
  184.     erase
  185.     device, font = font
  186.     xyouts, 10, !d.y_size - 1.5 * !d.y_ch_size, /DEV, /FONT, display_string
  187.     wset, swin
  188.     ENDCASE
  189.     "PRIV":  BEGIN
  190.     WIDGET_CONTROL, reg_base, map=0
  191.     WIDGET_CONTROL, s_list, SET_VALUE = s[private]
  192.     priv = 1
  193.     ENDCASE
  194.     "REG":   BEGIN
  195.     WIDGET_CONTROL, reg_base, map=1
  196.     priv = 0
  197.     q = xfont_select(s_string)    ;Matching fonts
  198.     goto, update_s_list
  199.     ENDCASE
  200.  
  201.     "DRAW": WIDGET_CONTROL, event.top, /DESTROY   ;Clicked draw window
  202.  
  203.     "VIEW": BEGIN
  204.     if selected_font lt 0 then return
  205.     device, font = xfont_scal_fname(s[selected_font])
  206.     junk = WIDGET_BASE(title = s[selected_font])
  207.     chx = !d.x_ch_size * 2. > 8    ;X Spacing
  208.     chy = !d.y_ch_size * 1.7 > 12    ;Y Spacing
  209.     draw = WIDGET_DRAW(junk, xsize = chx * 18, ysize = chy * 18, $
  210.         /BUTTON_EVENTS, UVALUE="DRAW", RET=2)
  211.     WIDGET_CONTROL, junk, /realize
  212.     WIDGET_CONTROL, draw, GET_VALUE = i
  213.     swin = !D.WINDOW
  214.     WSET, i
  215.     for i=0,15 do xyouts, (i+2)*chx, !d.y_size - chy, /DEV, $
  216.         string(i, format='(z1)')
  217.     for i= 0, 15 do begin
  218.         y = !d.y_size - (i+2) * chy
  219.         xyouts, 0, y, /DEV, string(i, format='(z1)')
  220.         k = i*16
  221.         for j=0, 15 do $
  222.             if j+k ne 0 then xyouts, (j+2) *chx, y, /DEV, /FONT, $
  223.                 string(byte(j+k))
  224.         ENDFOR
  225.     WSET, swin
  226.     XMANAGER, 'xfont', junk, EVENT_HANDLER = 'xfont_event', $
  227.         GROUP_LEADER = event.top
  228.     ENDCASE
  229.     "HELP": BEGIN
  230. ;    xdisplayfile, 'xfont.txt', $    ;Debugging
  231.     xdisplayfile, filepath("xfont.txt", subdir=['help', 'widget']), $  ;Working
  232.         title = "xfont help", $
  233.         group = event.top, $
  234.         width = 72, height = 24
  235.     ENDCASE
  236.  
  237.     "STEXT": BEGIN
  238.     WIDGET_CONTROL, s_text, GET_VALUE = display_string
  239.     display_string = display_string[0]
  240.     goto, view_font
  241.     ENDCASE
  242.  
  243.     "PTXT": goto, view_font    
  244.     "DONE": BEGIN
  245.     if selected_font ge 0 then begin
  246.         s_string = xfont_scal_fname(s[selected_font])
  247.         goto, exit
  248.         endif
  249.     ENDCASE
  250.     "CANCEL": BEGIN
  251.     selected_font = -1
  252.     exit:
  253.     WIDGET_CONTROL, event.top, /DESTROY
  254.     if preserve eq 0 then BEGIN    ;Clean up space consuming arrays
  255.         f = 0
  256.         if selected_font ge 0 then s = s[selected_font] else s = ''
  257.         private = 0
  258.         uniqs = 0
  259.         xreg = 0
  260.         ENDIF
  261.     ENDCASE
  262. ENDCASE
  263. END
  264.  
  265.  
  266.  
  267.  
  268. Function xfont, GROUP = GROUP, PRESERVE_FONT_INFO = pres
  269.  
  270. common xfont_com, s, f, xreg, private, nfields, nreg, uniqi, uniqs, $
  271.     t_buttons, t_list, s_list, s_string, t_button_select, t_text, $
  272.     l_text, to_do, t_selections, selected_font, view_text, $
  273.     view_window, reg_base, priv, display_string, s_text, preserve, $
  274.     point_base, point_txt, size_index
  275.                      
  276.  
  277.    ; Return to caller if run on Windows or Macintosh since this routine
  278.    ; only applies to X Windows platforms.
  279.    ON_ERROR, 2                     ;Return to caller if an error occurs
  280.    IF (!VERSION.OS_FAMILY EQ 'Windows' OR $
  281.        !VERSION.OS_FAMILY EQ 'MacOS') THEN BEGIN
  282.       MESSAGE,"This routine is not supported on this platform.",/CONTINUE
  283.       RETURN,''
  284.    ENDIF
  285.  
  286.    ; Check for other copies and do nothing if xfont is already running:
  287.  
  288.    IF(XRegistered('xfont') NE 0) THEN RETURN, ''
  289.  
  290.    if n_elements(pres) gt 0 then preserve = pres else preserve = 0
  291.    pwin = -1
  292.    selected_font = -1
  293.    t_button_select = -1
  294.    priv = 0
  295.    display_string = 'The quick brown fox jumped over the lazy dog.' + $
  296.     '!C!CABCDEFG abcdefg 01234567'
  297.  
  298.    to_do = [ 0,1,2,3,4,7 ]    ;Fields we care about
  299.    m = n_elements(to_do)
  300.    field_names = [ 'Foundry', 'Family', 'Weight', 'Slant', 'Width', $
  301.         'Size' ]
  302.    t_buttons = lonarr(m)
  303.    t_text = lonarr(m)
  304.    s_string = replicate('*', m)
  305.    size_index = 5        ;The index of the point size field
  306.  
  307.  
  308.    if !d.window lt 0 then $    ;So we don't create an empty window
  309.     window, /pix, xs=100, ys=100, /free, pwin
  310.  
  311.    if n_elements(s) gt 1 then goto, processed_fonts  ;Saved info?
  312.    t0 = systime(1)
  313.    device, font ='*', get_fontname=s      ;Get the fonts
  314.    nf = n_elements(s)            ;# of fonts
  315.  
  316.    char1 = strmid(s, 0, 1)        ;Parse fontname strings
  317.    ext = where(char1 eq '+', count)      ;Any Font name extensions?
  318.    for i=0, count-1 do begin        ;Remove them
  319.     j = ext[i]
  320.     s[j] = strmid(s[j], strpos(s[j], '-'), 1000)
  321.     endfor
  322.                 ;Separate the X window fonts
  323.    if count gt 0 then xreg = [ where(char1 eq '-'), ext ] $
  324.    else xreg = where(char1 eq '-')
  325.  
  326.    private = lonarr(nf)        ;Get private fonts
  327.    private[xreg] = 1        ;Ones that are X
  328.    private = where(private eq 0)  ;Ones that aren't
  329.    private = private[sort(s[private])]  ;Sort into lexical order
  330.  
  331.    nreg = n_elements(xreg)    ; Separate information from font names
  332.  
  333.    f = strarr(m, nreg)        ;Fields we care about
  334.    nfields = max(to_do)
  335.    this_one = replicate(-1, nfields+1)  ;-1 in fields we don't want
  336.    this_one[to_do] = indgen(m)    ;Index in ones we do
  337.  
  338.    for j=0, nreg-1 do begin    ;Each registered font
  339.     t = s[xreg[j]]        ;The string
  340.     anchor = 1        ;1st char to search
  341.     for i=0, nfields do begin    ;Extract each field
  342.         n = strpos(t, '-', anchor)
  343.         k = this_one[i]
  344.         if k ge 0 then begin
  345.            tt = strmid(t, anchor, n - anchor)
  346.            if tt eq '' then f[k,j] = '<blank>' else f[k,j] = tt
  347.            endif
  348.         anchor = n + 1
  349.         endfor
  350.     endfor
  351.  
  352.    uniqi = lonarr(m+1)        ;Indices to unique names
  353.    
  354.    for i=0L, m-1 do begin    ;Get unique items for each field
  355.     t = f[i,*]
  356.     t = uniq(t, sort(t))
  357.     uniqi[i+1] = n_elements(t) + uniqi[i]    ;Startind indices
  358.     if i eq 0 then uniqs = t $
  359.     else uniqs = [ uniqs, t]
  360.     endfor
  361. ;   print, systime(1) - t0, ' seconds getting fonts'
  362.  
  363.  
  364. processed_fonts:
  365.    xfontbase = WIDGET_BASE(TITLE='Font Widget', /COLUMN)
  366.    junk = WIDGET_BASE(xfontbase, /ROW)
  367.    junk1 = WIDGET_BUTTON(junk, value = "OK", UVALUE = "DONE", /NO_REL)
  368.    junk1 = WIDGET_BUTTON(junk, value = "Cancel", UVALUE = "CANCEL", /NO_REL)
  369.    junk1 = WIDGET_BUTTON(junk, value = "View", UVALUE = "VIEW", /NO_REL)
  370.    junk1 = WIDGET_BUTTON(junk, value = "Help", UVALUE = "HELP", /NO_REL)
  371.    junk1 = WIDGET_BASE(junk, /ROW, /EXCLUSIVE)
  372.    junk2 = WIDGET_BUTTON(junk1, VALUE = 'Registered', UVALUE='REG')
  373.    junk3 = WIDGET_BUTTON(junk1, VALUE = 'Private', UVALUE='PRIV')
  374.    WIDGET_CONTROL, junk2, SET_BUTTON=1
  375.    
  376.    point_base = WIDGET_BASE(junk, /ROW, /FRAME)
  377.    junk2 = WIDGET_LABEL(point_base, VALUE='deciPoint Size:')
  378.    point_txt = WIDGET_TEXT(point_base, xsize=4, /EDIT, value='120', $
  379.         UVALUE='PTXT')
  380.    WIDGET_CONTROL, point_base, MAP=0
  381.  
  382.    reg_base = WIDGET_BASE(xfontbase, /ROW)
  383.    lbase = WIDGET_BASE(reg_base, /COLUMN)
  384.    rbase = WIDGET_BASE(reg_base, /COLUMN)
  385.  
  386.    for i=0, n_elements(to_do)-1 do begin    ;Make exclusive bases
  387.     j = to_do[i]
  388.     junk = widget_base(lbase, /ROW, /FRAME)
  389.     junk2 = WIDGET_BASE(junk, /EXCLUSIVE)
  390.     t_buttons[i] = $
  391.         WIDGET_BUTTON(junk2, value= field_names[i], /NO_RELEASE, $
  392.             UVALUE='TBUTTON')
  393.     t_text[i] = WIDGET_TEXT(junk, value = '*', ysize=1, xsize=24)
  394.     endfor
  395.    ; Set all the buttons to the width of the widest
  396.    junk = max(strlen(field_names), junk2)
  397.    geo = WIDGET_INFO(t_buttons[junk2], /geometry)
  398.    for i=0, n_elements(to_do)-1 do $
  399.        widget_control, scr_xsize=geo.scr_xsize, t_buttons[i]
  400.  
  401.    l_text = WIDGET_TEXT(lbase, /FRAME, xsize = 32)
  402.  
  403.    t_list = WIDGET_LIST(rbase, value = string(replicate(77b,24)), $
  404.             UVALUE = 'T_LIST', ysize = 9)
  405.  
  406.    base = xfontbase
  407.    s_list = WIDGET_LIST(base, value = string(replicate(77b,56)), $
  408.             UVALUE = 'S_LIST', ysize = 8)
  409.  
  410.    junk  = WIDGET_BASE(base, /ROW, /FRAME)
  411.    junk1 = WIDGET_LABEL(junk, VALUE='Current font:')
  412.    view_text = WIDGET_TEXT(junk, value = string(replicate(77B, 64)), $
  413.         XSIZE=64)
  414.  
  415.    junk = WIDGET_BASE(base, /ROW, /FRAME)
  416.    junk1 = WIDGET_LABEL(junk, VALUE='Display Text:')
  417.    s_text = WIDGET_TEXT(junk, value = display_string, $
  418.         XSIZE=64, UVALUE = "STEXT", /EDIT)
  419.  
  420.    view_draw = WIDGET_DRAW(base, xsize = 400, ysize=120, RETAIN = 2)
  421.    
  422.    WIDGET_CONTROL, xfontbase, /REALIZE
  423.  
  424.    WIDGET_CONTROL, t_list, SET_VALUE=' '    ;Remove beginning junk
  425.    WIDGET_CONTROL, s_list, SET_VALUE=' '
  426.    WIDGET_CONTROL, view_text, SET_VALUE=' '
  427.    WIDGET_CONTROL, view_draw, GET_VALUE = view_window
  428.  
  429.    ; Register the widgets with the XManager.
  430.  
  431.    if pwin ge 0 then wdelete, pwin        ;Clean up initialization
  432.    XManager, 'xfont', xfontbase, $
  433.                 EVENT_HANDLER = 'xfont_event', $
  434.         GROUP_LEADER = GROUP
  435.  
  436.    if selected_font lt 0 then return, '' else $
  437.     return, s_string
  438. END
  439.